package com.bumptech.glide.load.resource.drawable;

import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.Drawable.ConstantState;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;

import com.bumptech.glide.load.engine.Initializable;
import com.bumptech.glide.load.engine.Resource;
import com.bumptech.glide.load.resource.gif.GifDrawable;
import com.bumptech.glide.util.Preconditions;

/**
 * Simple wrapper for an Android {@link Drawable} which returns a
 * {@link ConstantState#newDrawable() new drawable}
 * based on it's {@link ConstantState state}.
 * <p>
 * 简单封装一个通过{@link Drawable.ConstantState#newDrawable()}来生成{@link Drawable}的抽象类
 * <p>
 * <b>Suggested usages only include {@code T}s where the new drawable is of the same or descendant
 * class.</b>
 *
 * @param <T> type of the wrapped {@link Drawable}
 */
public abstract class DrawableResource<T extends Drawable> implements Resource<T>,
        Initializable {
    protected final T drawable;

    public DrawableResource(T drawable) {
        this.drawable = Preconditions.checkNotNull(drawable);
    }

    @NonNull
    @SuppressWarnings("unchecked")
    @Override
    public final T get() {
        @Nullable ConstantState state = drawable.getConstantState();
        if (state == null) {
            return drawable;
        }
        // Drawables contain temporary state related to how they're being displayed
        // (alpha, color filter etc), so return a new copy each time.
        // If we ever return the original drawable, it's temporary state may be changed
        // and subsequent copies may end up with that temporary state. See #276.
        return (T) state.newDrawable();
    }

    @Override
    public void initialize() {
        if (drawable instanceof BitmapDrawable) {
            ((BitmapDrawable) drawable).getBitmap().prepareToDraw();
        } else if (drawable instanceof GifDrawable) {
            ((GifDrawable) drawable).getFirstFrame().prepareToDraw();
        }
    }
}
